﻿#define _CRT_SECURE_NO_WARNINGS 1

//malloc函数 --- ⼀个动态内存开辟的函数
//这个函数向内存申请⼀块连续可⽤的空间，并返回指向这块空间的指针。
//• 如果开辟成功，则返回⼀个指向开辟好空间的指针。
//• 如果开辟失败，则返回⼀个 NULL 指针，因此malloc的返回值⼀定要做检查。
//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	//申请存放5个整型大小的空间
//	int* p = (int*)malloc(sizeof(int) * 5);
//	if (p == NULL)
//	{
//		perror("malloc");
//		return;
//	}
//	//使用
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		*(p + i) = i + 1;
//	}
//
//	for (i = 0; i < 5; i++)
//	{
//		printf("%d ", *(p + i));
//	}
//
//
//	//free函数⽤来释放动态开辟的内存。
//	//	• 如果参数 ptr 指向的空间不是动态开辟的，那free函数的⾏为是未定义的。
//	//	• 如果参数 ptr 是NULL指针，则函数什么事都不做。
//	//释放空间
//	free(p);//传递给free函数的是要释放的内存空间的起始地址
//	p = NULL;
//
//	return 0;
//}



//calloc --- 函数也⽤来动态内存分配
//• 函数的功能是为 num 个⼤⼩为 size 的元素开辟⼀块空间，并且把空间的每个字节初始化为0。
//• 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	int* p = (int*)calloc(10, sizeof(int));
//	if (p == NULL)
//	{
//		perror("calloc");
//		return;
//	}
//
//	//使用
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", *(p + i));
//	}
//
//	//释放空间
//	free(p);
//	p = NULL;
//
//	return 0;
//}


//realloc --- 函数就可以做到对动态开辟内存⼤⼩的调整。
//情况1
//当是情况1 的时候，要扩展内存就直接原有内存之后直接追加空间，原来空间的数据不发⽣变化。
//情况2
//当是情况2 的时候，原有空间之后没有⾜够多的空间时，扩展的⽅法是：在堆空间上另找⼀个合适⼤⼩
//的连续空间来使⽤。这样函数返回的是⼀个新的内存地址。

//#include<stdio.h>
//#include<stdlib.h>
//
//int main()
//{
//	int* p = (int*)malloc(sizeof(int) * 5);
//	if (p == NULL)
//	{
//		perror("malloc");
//		return;
//	}
//
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		*(p + i) = i + 1;
//	}
//
//	//将空间调整为可以存放10个整型大小
//	int* tmp = (int*)realloc(p, sizeof(int) * 10);
//	if (tmp == NULL)//调整失败
//	{
//		perror("realloc");
//		free(p);
//		p = NULL;
//	}
//	else//调整成功
//	{
//		p = tmp;
//		int i = 0;
//		for (i = 5; i < 10; i++)
//		{
//			*(p + i) = i + 1;
//		}
//
//		for (i = 0; i < 10; i++)
//		{
//			printf("%d ", *(p + i));
//		}
//
//		//释放空间
//		free(p);
//		p = NULL;
//	}
//
//	return 0;
//}


//忘记释放不再使⽤的动态开辟的空间会造成内存泄漏

//#include<stdio.h>
//#include<stdlib.h>


////题⽬1：
//void GetMemory(char* p)
//{
//	p = (char*)malloc(100);
//}
//void Test(void)
//{
//	char* str = NULL;
//	GetMemory(str);
//	strcpy(str, "hello world");
//	printf(str);
//}


////题⽬2：
//char* GetMemory(void)
//{
//	char p[] = "hello world";
//	return p;
//}
//void Test(void)
//{
//	char* str = NULL;
//	str = GetMemory();
//	printf(str);
//}


////题⽬3：
//void GetMemory(char** p, int num)
//{
//	*p = (char*)malloc(num);
//}
//void Test(void)
//{
//	char* str = NULL;
//	GetMemory(&str, 100);
//	strcpy(str, "hello");
//	printf(str);
//}


////题⽬4：
//void Test(void)
//{
//	char* str = (char*)malloc(100);
//	strcpy(str, "hello");
//	free(str);
//	if (str != NULL)
//	{
//		strcpy(str, "world");
//		printf(str);
//	}
//}
//
//int main()
//{
//
//	Test();
//
//	return 0;
//}


//柔性数组

//C99 中，结构中的最后⼀个元素允许是未知⼤⼩的数组，这就叫做『柔性数组』成员

//struct S
//{
//	char c;
//	int n;
//	int arr[];//柔性数组
//};


//struct S
//{
//	char c;
//	int n;
//	int arr[0];//柔性数组
//};


//柔性数组的特点：
//• 结构中的柔性数组成员前⾯必须⾄少⼀个其他成员。
//• sizeof 返回的这种结构⼤⼩不包括柔性数组的内存。
//• 包含柔性数组成员的结构⽤malloc()函数进⾏内存的动态分配，并且分配的内存应该⼤于结构的⼤
//⼩，以适应柔性数组的预期⼤⼩。
//#include<stdio.h>
//typedef struct st_type
//{
//	int i;
//	int a[0];//柔性数组成员
//}type_a;
//int main()
//{
//	printf("%zd\n", sizeof(type_a));//输出的是4
//
//	return 0;
//}


#include<stdio.h>
#include<stdlib.h>

//struct S
//{
//	int n;
//	int arr[];
//};
//
//
//int main()
//{
//	//开辟空间
//	struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
//	if (ps == NULL)
//	{
//		perror("malloc");
//		return;
//	}
//
//	//使用
//	ps->n = 7;
//	int i = 0;
//	for (i = 0; i < 5; i++)
//	{
//		ps->arr[i] = i + 1;
//	}
//
//	//调整空间的大小
//	struct S* tmp = (struct S*)realloc(ps,sizeof(struct S) + 10 * sizeof(int));
//	if (tmp != NULL)
//	{
//		ps = tmp;
//		tmp = NULL;
//		for (i = 5; i < 10; i++)
//		{
//			ps->arr[i] = i + 1;
//		}
//
//		for (i = 0; i < 10; i++)
//		{
//			printf("%d ", ps->arr[i]);
//		}
//
//		free(ps);
//		ps = NULL;
//	}
//	else
//	{
//		perror("realloc");
//		//释放
//		free(ps);
//		ps = NULL;
//	}
//
//	return 0;
//}


struct S
{
	int n;
	int* arr;
};


int main()
{
	struct S* ps = (struct S*)malloc(sizeof(struct S));
	if (ps == NULL)
	{
		perror("malloc");
		return;
	}

	ps->arr = (int*)malloc(sizeof(int)*5);
	if (ps->arr == NULL)
	{
		perror("malloc");
		return;
	}

	ps->n = 3;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		ps->arr[i] = i + 1;
	}

	//调整大小
	int* tmp = (int*)realloc(ps->arr, sizeof(int) * 10);
	if (tmp != NULL)
	{
		ps->arr = tmp;
		tmp = NULL;
		for (i = 5; i < 10; i++)
		{
			ps->arr[i] = i + 1;
		}

		for (i = 0; i < 10; i++)
		{
			printf("%d ",ps->arr[i]);
		}

		free(ps->arr);
		ps->arr = NULL;
		free(ps);
		ps = NULL;
	}
	else
	{
		perror("realloc");
		free(ps->arr);
		ps->arr = NULL;
		free(ps);
		ps = NULL;
	}

	return 0;
}













